#include <linux/init.h>
#include <linux/module.h>
#include <linux/sched.h>
#include <linux/semaphore.h>
#include <linux/interrupt.h>
#include <linux/slab.h>
#include <linux/types.h>
#include <linux/unistd.h>
#include <linux/kernel.h>

static DECLARE_WAIT_QUEUE_HEAD(myqueue);

int hello(void)
{    
    DECLARE_WAITQUEUE(wait,current);
    daemonize("hello");    
    add_wait_queue(&myqueue,&wait);
    printk("hello\n");
    set_current_state(TASK_INTERRUPTIBLE);
    schedule();
    remove_wait_queue(&myqueue,&wait);
    printk("thread is over\n");
    return 0;

}

int H_init(void)
{
    int res = 0;
    printk(KERN_ALERT "Hello ...\n");
    kernel_thread(hello,NULL,CLONE_FS | CLONE_FILES | CLONE_SIGHAND | SIGCHLD );
    return res;
}

void H_exit(void)
{
    wake_up(&myqueue);
    printk(KERN_ALERT "Bye ...\n");
}
static int __init hdrv_init(void)
{
    printk(KERN_ALERT "driver loading ...\n");
    return H_init();
    
}


static void __exit hdrv_exit(void)
{
    printk(KERN_ALERT " driver unloaded.\n");
    H_exit();
}
MODULE_LICENSE("GPL");
module_init(hdrv_init);
module_exit(hdrv_exit);